package com.example.nypindoormap;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.GoogleMap;

import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;


public class MainActivity extends FragmentActivity {
	
	private static final int GPS_ERRORDIALOG_REQUEST = 9001;
	GoogleMap mMap; 
	
	private static final String TAG = "D";
	//** declare Variables **
	
	// Create the authentication object
	// myAndroidContext must be a Context instance
	
	
	
	double wifiAcc;
	double gpsAcc;
	double nypAcc;
	double gpsLat;
	double gpsLng;
	double wifiLat;
	double wifiLng;
	double nypLat;
	double nypLng;
	double ActualDisplayLat;
	double ActualDisplayLng;
	double wifiDistanceActual;
	double gpsDistanceActual;
	double nypDistanceActual;
	double wifiDistanceGps;
	double gpsalt;
	
	LocationManager locationManager;
	LocationListener gpsLocationListener;
	LocationListener wifiLocationListener;
	LocationListener locationListener;

	
	EditText ActualDisplay;
	EditText GPS;
	EditText Wifi;
	EditText NYP;
	EditText level;
	Button map;
	Button mapBtn;
	
	
	String networkOperator;
	Boolean result;
	
	// variable to determine whether provider are connected.
	boolean gpsProvider = false;
	boolean wifiProvider = false;
	

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);
        
           //display view
        
    //** Find view of EditText *//*
        
        // for gps
        GPS = (EditText) findViewById(R.id.GPS);
    
     	// for wifi
        Wifi = (EditText) findViewById(R.id.Wifi);
     	
     	// for nypculated
        NYP = (EditText) findViewById(R.id.NYP);
     	
     	// for location
        //ActualDisplay = (EditText) findViewById(R.id.ActualDisplay);
     	
     	// set Hardcoded actual location to text
     	//ActualDisplayLat = 1.379524;
     	//ActualDisplayLng = 103.848843;
     	//String actualText = String.format("Desc:\t Block S level 4 \nLat:\t %f\nLong:\t %f", ActualDisplayLat, ActualDisplayLng);
     	//ActualDisplay.setText(actualText);
     	
     
     	
 	// ** Find view of button **
     	
     	// for check mapBTN
     	map = (Button) findViewById(R.id.map);
     	
     	mapBtn = (Button) findViewById(R.id.map);
     	
     	map.setOnClickListener(new OnClickListener() {
			
     		@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Intent intent = new Intent(MainActivity.this, MapActivity.class);
				startActivity(intent);
				
				
				
				
				
				
			}
		});
     	
     	mapBtn.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Intent intent = new Intent(MainActivity.this, MapActivity.class);
				startActivity(intent);
				
			}
		});
     	
     
    
     	
     	// Acquire a reference to the system Location Manager for GPS and WIFI
 		locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
 		
 	

     	
     	locationListener = new LocationListener() {
        
     		@Override
			public void onLocationChanged(Location location) {
     		// called when the listener is notified with a location update from the GPS
	    	// nypled when a new location is found by the network location provider.
  			// Generate location based on provider
			     if(location.getProvider().contains("gps")) {
		 		     gpsNewLocation(location);
			     }
			     if(location.getProvider().contains("network")) {
		 		     wifiNewLocation(location);
		
			     }
			     
			     NYPNewLocation(gpsLat,gpsLng,gpsAcc,wifiLat,wifiLng,wifiAcc);
 		    }

 		    @Override
			public void onStatusChanged(String provider, int status, Bundle extras) {}
 		    
 		    // called when the status of the GPS provider changes

 		    @Override
			public void onProviderEnabled(String provider) {}
 		    
 		    // called when the GPS provider is turned on (user turning on the GPS on the phone)

 		    @Override
			public void onProviderDisabled(String provider) {}
 		    // called when the GPS provider is turned off (user turning off the GPS on the phone)

 		    
 		  };
 		  
 		// Request Location
 		 locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
  		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
  		
  		setupMessageButton();
    }
    
        private void setupMessageButton() {
        	//1. get a reference to the button
        	Button messageButton = (Button) findViewById(R.id.map);
        	
        	
        	//2. Set the click listener to run my code.
        	View.OnClickListener myListener = new View.OnClickListener() {
        		
        		private Location location;

				@Override
        		public void onClick(View v) {
        			
        			//creating a new intent
        			//Intent myIntent = new Intent(getApplicationContext(), MapActivity.class);
        			//startActivity(myIntent);
					Intent intent= new Intent(MainActivity.this, MapActivity.class);
			     	Bundle o = new Bundle();
			     	o.putDouble("key",gpsalt);
			     	intent.putExtras(o);
			     	startActivity(intent);
					
				
        			// TODO Auto-generated method stub
        			Log.i(TAG, "You clicked the button!");
        			Toast.makeText(MainActivity.this,
        					"You clicked map!",
        					Toast.LENGTH_LONG)
        			.show();
        			
        		
        		}
        	};
        	messageButton.setOnClickListener(myListener);
        }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
        
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatinyply handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    
public void startMap(View view) {
	
	
	
    	
    	startActivity(new Intent("com.example.MapActivity"));
    	
    	final Button button = (Button) findViewById(R.id.map);
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // Perform action on click   

                Intent activityChangeIntent = new Intent(MainActivity.this, MapActivity.class);

                // currentContext.startActivity(activityChangeIntent);

                MainActivity.this.startActivity(activityChangeIntent);
            }
        });
    }



	
    
    public void gpsNewLocation(Location location) {
 		// TODO Auto-generated method stub
     	Log.d(TAG, "onLocationChanged with location " + location.toString());
     	
     	
     	gpsalt=location.getAltitude();
     	gpsLat = location.getLatitude();
      	gpsLng = location.getLongitude();
      	gpsAcc = location.getAccuracy();
      	
      	// nypculate distance from actual
      	double gpsActualLatPow = Math.pow((gpsLat - ActualDisplayLat), 2);
      	double gpsActualLngPow = Math.pow((gpsLng - ActualDisplayLng), 2);
      	double combineGpsPow = gpsActualLatPow + gpsActualLngPow;
      	gpsDistanceActual =  Math.sqrt(combineGpsPow) * 1.1 * Math.pow(10,5);
      	
     	// if gps is provider
     	String gpsText = String.format("Lat:\t %f\nLong:\t %f\nAlt:\t %f\nBearing:\t %f \nAccuracy:\t %f\nDistanceFromActual:\t %fm", location.getLatitude(), location.getLongitude(), location.getAltitude(), location.getBearing(), location.getAccuracy(),gpsDistanceActual);
       
     	// Set Text
     	GPS.setText(gpsText);
 	}
    
    protected void wifiNewLocation(Location location) {
		// TODO Auto-generated method stub
    	Log.d(TAG, "onLocationChanged with location " + location.toString());
    	
    	wifiLat = location.getLatitude();
     	wifiLng = location.getLongitude();
     	wifiAcc = location.getAccuracy();
     	
     	// nypculate distance from actual
     	double wifiActualLatPow = Math.pow((wifiLat - ActualDisplayLat), 2);
     	double wifiActualLngPow = Math.pow((wifiLng - ActualDisplayLng), 2);
     	double combineWifiPow = wifiActualLatPow + wifiActualLngPow;
     	wifiDistanceActual =  Math.sqrt(combineWifiPow) * 1.1 * Math.pow(10,5);
     	
     	
     	// set string
    	String wifiText = String.format("Lat:\t %f\nLong:\t %f\nAccuracy:\t %f\nDistanceFromActual:\t %fm", location.getLatitude(), location.getLongitude(), /*location.getAltitude()*/location.getAccuracy(), wifiDistanceActual); 	
    	// Getting provider
    	String provider = location.getProvider();
    	
    	// Set Text
    	Wifi.setText(wifiText);
     	
	}
    
    protected void NYPNewLocation(double gpsLat, double gpsLng, double gpsAcc,
			double wifiLat, double wifiLng, double wifiAcc) {
		// TODO Auto-generated method stub
		Log.d(TAG, "onLocationChanged with nypculation ");
		
		/** apply formula */
		
		// nypculate distance of gps from Wifi
     	double gpsWifiLatPow = Math.pow((gpsLat - wifiLat), 2);
     	double gpsWifiLngPow = Math.pow((gpsLng - wifiLng), 2);
     	double combineGpsWifiPow = gpsWifiLatPow + gpsWifiLngPow;
     	wifiDistanceGps =  Math.sqrt(combineGpsWifiPow) * 1.1 * Math.pow(10,5);
     	
     	// nypculation of accuracy of nypculated position
     	nypAcc = Math.sqrt( 1/( (1/(Math.pow(gpsAcc, 2)) + (1/(Math.pow(gpsAcc, 2))) ) ) );
		
		//if 2 * nypAcc > wifiDistanceGps
     	if((2 * nypAcc) > wifiDistanceGps)
     	{
     	// if gpsAcc > wifiAcc
			if(gpsAcc > wifiAcc)
			{
				nypLat = ( ( ( 1/(Math.pow(gpsAcc, 2)) ) / ( ( 1/(Math.pow(gpsAcc, 2))) + ( 1/(Math.pow(wifiAcc, 2))) ) ) * (gpsLat) ) + ( ( ( 1/(Math.pow(wifiAcc, 2)) ) / ( ( 1/(Math.pow(gpsAcc, 2))) + ( 1/(Math.pow(wifiAcc, 2))) ) ) * (wifiLat) );
	     		nypLng = ( ( ( 1/(Math.pow(gpsAcc, 2)) ) / ( ( 1/(Math.pow(gpsAcc, 2))) + ( 1/(Math.pow(wifiAcc, 2))) ) ) * (gpsLng) ) + ( ( ( 1/(Math.pow(wifiAcc, 2)) ) / ( ( 1/(Math.pow(gpsAcc, 2))) + ( 1/(Math.pow(wifiAcc, 2))) ) ) * (wifiLng) );
			}
			else
			{
				nypLat = ( ( ( 1/(Math.pow(wifiAcc, 2)) ) / ( ( 1/(Math.pow(gpsAcc, 2))) + ( 1/(Math.pow(wifiAcc, 2))) ) ) * (gpsLat) ) + ( ( ( 1/(Math.pow(gpsAcc, 2)) ) / ( ( 1/(Math.pow(gpsAcc, 2))) + ( 1/(Math.pow(wifiAcc, 2))) ) ) * (wifiLat) );
	     		nypLng = ( ( ( 1/(Math.pow(wifiAcc, 2)) ) / ( ( 1/(Math.pow(gpsAcc, 2))) + ( 1/(Math.pow(wifiAcc, 2))) ) ) * (gpsLng) ) + ( ( ( 1/(Math.pow(gpsAcc, 2)) ) / ( ( 1/(Math.pow(gpsAcc, 2))) + ( 1/(Math.pow(wifiAcc, 2))) ) ) * (wifiLng) );
			}
     	}
		
		// else
     	else
     	{
     		nypLat = ( ( ( 1/(Math.pow(gpsAcc, 2)) ) / ( ( 1/(Math.pow(gpsAcc, 2))) + ( 1/(Math.pow(wifiAcc, 2))) ) ) * (gpsLat) ) + ( ( ( 1/(Math.pow(wifiAcc, 2)) ) / ( ( 1/(Math.pow(gpsAcc, 2))) + ( 1/(Math.pow(wifiAcc, 2))) ) ) * (wifiLat) );
     		nypLng = ( ( ( 1/(Math.pow(gpsAcc, 2)) ) / ( ( 1/(Math.pow(gpsAcc, 2))) + ( 1/(Math.pow(wifiAcc, 2))) ) ) * (gpsLng) ) + ( ( ( 1/(Math.pow(wifiAcc, 2)) ) / ( ( 1/(Math.pow(gpsAcc, 2))) + ( 1/(Math.pow(wifiAcc, 2))) ) ) * (wifiLng) );
     	}
		
		
		// nypculate distance from actual
     	double nypActualLatPow = Math.pow((nypLat - ActualDisplayLat), 2);
     	double nypActualLngPow = Math.pow((nypLng - ActualDisplayLng), 2);
     	double combinenypPow = nypActualLatPow + nypActualLngPow;
     	nypDistanceActual =  Math.sqrt(combinenypPow) * 1.1 * Math.pow(10,5);
     	
		String nypText = String.format("Lat:\t %f\nLong:\t %f\nAccuracy:\t %f\nDistanceFromActual:\t %fm", nypLat, nypLng,nypAcc,nypDistanceActual);
		// set Text
		NYP.setText(nypText);
		
		
    }
    


    
    public boolean servicesOK(){
    	int isAvailable = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
    	
    	if (isAvailable == ConnectionResult.SUCCESS) {
    		return true;
    	}
    	else if (GooglePlayServicesUtil.isUserRecoverableError(isAvailable)){
    		Dialog dialog = GooglePlayServicesUtil.getErrorDialog(isAvailable, this, GPS_ERRORDIALOG_REQUEST);
    		dialog.show();
    		}
    	else{
    		Toast.makeText(this,"Can't connect to Google Play services",Toast.LENGTH_SHORT).show();
    }
    	return false;}
    
    
}
